package org.xiph.vorbis
{
	import flash.utils.ByteArray;

	import cmodule.vorbisdec.CLibInit;

	/**
	 * class VorbisAlchemyDecoder is hiding all communication with the Alchemy part.
	 *
	 * Does not work without the Alchemy compiled vorbisdec.swc
	 *
	 * @author Eugene Zatepyakin
	 * @author Andre Michelle
	 */
	internal final class VorbisAlchemyDecoder
	{
		private static const VORBIS_LIB:Object = new CLibInit().init();
		private static const ns:Namespace = new Namespace( "cmodule.vorbisdec" );
		public static const ram:ByteArray = ns::gstate.ds;

		private var _oggID:int = -1;
		private var _outPtr:int = -1;
		private var _durPtr:int;

		public function get vorbisDecPtr():int
		{
			return _outPtr;
		}

		public function vorbisInit( file: ByteArray, bytesTotal: uint ):VorbisInfo
		{
			const minSamplesToReturn:int = 1024;
			const samplesPerDecodeStep:int = 1024;

			const initValues: Array = VORBIS_LIB['startDecode']( file, bytesTotal, minSamplesToReturn, samplesPerDecodeStep );

			_oggID = initValues[0];
			_outPtr = initValues[1];
			_durPtr = initValues[3];

			return new VorbisInfo( initValues[2] ); // INFO OBJECT
		}

		public function vorbisDecode():int
		{
			return VORBIS_LIB['decodeBlock']( _oggID );
		}

		public function vorbisSeekTime( time:Number ):Number
		{
			return VORBIS_LIB['seekTime']( _oggID, time );
		}

		public function vorbisSeekSample( index:Number ):void
		{
			VORBIS_LIB['seekSample']( _oggID, index );
		}

		public function vorbisPosition():Number
		{
			return VORBIS_LIB['getPosition']( _oggID );
		}
		
		public function vorbisSamplePosition():Number
		{
			return VORBIS_LIB['getSamplePosition']( _oggID );
		}

		public function vorbisSampleDuration():Number
		{
			const r: int = VORBIS_LIB['refreshFileInfo']( _oggID );

			ram.position = _durPtr;

			return ram.readDouble();
		}

		public function vorbisFree():void
		{
			VORBIS_LIB['freeDecoder']( _oggID );
		}

		public function toString():String
		{
			return '[VorbisAlchemy]';
		}
	}
}